package com.lord.otter.component.tools.business.chain;


import com.lord.otter.component.context.spring.StaticSpringContext;
import com.lord.otter.component.exception.BusinessException;
import com.lord.otter.component.exception.CommonExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @param <C> 业务执行的入参
 * @param <T> 业务上下文属性枚举定义类
 * @param <H> 业务执行器的实现类
 */
@Slf4j
public class BusinessHandlerManger<C, T extends BusinessContextAttributeDefinitionTable, H extends BusinessHandler<C, T>> {


    private List<H> businessHandlers;

    private BusinessHandlerLogAppender logAppender;

    public BusinessHandlerManger<C, T, H> addHandler(H h) {
        businessHandlers.add(h);
        return this;
    }

    public BusinessHandlerManger<C, T, H> addHandler(List<H> handler) {
        businessHandlers.addAll(handler);
        return this;
    }

    public void clean() {
        businessHandlers.clear();
    }

    public BusinessContext<T> exec(C c, BusinessContext<T> context) {
        if (Objects.isNull(c)) {
            throw CommonExceptionEnum.LACK_PARAM.exceptionMessage("命令是空的");
        }
        if (CollectionUtils.isEmpty(businessHandlers)) {
            throw CommonExceptionEnum.LACK_PARAM.exceptionMessage("没有注册业务处理器");
        }
        if (context == null) {
            context = new BusinessContext<>();
        }
        doExec(c, context);
        return context;
    }

    private void doExec(C c, BusinessContext<T> context) {
        String execId = UUID.randomUUID().toString();
        int i = 1;
        for (H handler : businessHandlers) {
            try {
                log.info("执行业务执行器的名字:" + handler.getName());
                log.info("执行业务执行器的执行序号:" + execId);
                handler.handle(c, context);
                if (i == 1) {
                    logAppender.addSuccessLog(execId, handler.getName(), i, null, c);
                } else if (i == businessHandlers.size()) {
                    logAppender.addSuccessLog(execId, handler.getName(), i, context, null);
                } else {
                    logAppender.addSuccessLog(execId, handler.getName(), i, null, null);
                }
                i++;
            } catch (Exception e) {
                log.error("执行业务执行器的名字:" + handler.getName());
                log.error("执行业务执行器的执行序号:" + execId);
                log.error("执行业务执行器错误", e);
                logAppender.addFailLog(execId, handler.getName(), i, c, context, e);
                if (e instanceof BusinessException) {
                    throw new BusinessException(((BusinessException) e).getCode(),
                            "业务执行错误的id[" + execId + "];错误信息:" + ((BusinessException) e).getMessage());
                } else {
                    throw e;
                }

            }
        }
    }

    public static <X, Y extends BusinessContextAttributeDefinitionTable, Z extends BusinessHandler<X, Y>> BusinessHandlerManger<X, Y, Z> create() {
        return create(new ArrayList<>());
    }


    public static <X, Y extends BusinessContextAttributeDefinitionTable, Z extends BusinessHandler<X, Y>> BusinessHandlerManger<X, Y, Z> create(List<Z> businessHandlers) {
        BusinessHandlerManger<X, Y, Z> manager = new BusinessHandlerManger<>();
        manager.businessHandlers = businessHandlers;
        manager.logAppender = StaticSpringContext.getBean(BusinessHandlerLogAppender.class);
        return manager;
    }


}
